package com.example.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.FootPrint;
import com.example.entity.Sku;
import com.example.entity.buyer.FootPrintPo;
import com.example.mapper.FootPrintMapper;
import com.example.vo.buyer.SpuSkuDetail;
import com.example.mapper.SkuMapper;
import com.example.mapper.SpuMapper;
import com.example.service.FootPrintService;
import com.example.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author 朽
*/
@Service
@Slf4j
public class FootPrintServiceImpl extends ServiceImpl<FootPrintMapper, FootPrint>
    implements FootPrintService{

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public List<SpuSkuDetail> getDetail(Long userId) {
        String redisKey = "user:" + userId + ":foot";
        Object cachedDetails = redisUtil.get(redisKey);
        if (cachedDetails != null) {
            List<SpuSkuDetail> details = (List<SpuSkuDetail>) cachedDetails;
            return filterDetailsWithDeleteFlagZero(details);
        } else {
            List<SpuSkuDetail> details = processFootPrints(userId);
            redisUtil.set(redisKey, details);
            return filterDetailsWithDeleteFlagZero(details);
        }
    }

    public List<SpuSkuDetail> processFootPrints(Long userId){
        List<Long> spuIds = baseMapper.getSpuIdByUserId(userId);
        List<SpuSkuDetail> details = new ArrayList<>();
        for (Long spuId : spuIds) {
            Date footprintTime = baseMapper.getFootprintTimeBySpuId(userId, spuId);
            Integer flag = baseMapper.getFlagBySpuId(userId, spuId);
            SpuSkuDetail detail = addFootPrints(spuId, footprintTime, flag);
            details.add(detail);
        }
        return details;
    }

    public SpuSkuDetail addFootPrints(Long spuId, Date footprintTime, Integer flag){
        // 获取Spu名称
        String spuName = spuMapper.getSpuNameBySpuIds(spuId);

        // 获取Sku信息
        List<Sku> relevantSkus = skuMapper.getSkuBySpuId(spuId);

        if (!relevantSkus.isEmpty()) {
            // 选择价格最低的Sku
            Sku cheapestSku = relevantSkus.stream()
                    .min(Comparator.comparing(Sku::getPrice))
                    .orElseThrow(() -> new IllegalStateException("没有找到SPU ID: " + spuId));

            // 构建SpuSkuDetail对象
            SpuSkuDetail detail = new SpuSkuDetail();
            detail.setId(spuId);
            detail.setName(spuName);
            detail.setDefaultImage(cheapestSku.getDefaultImage());
            detail.setPrice(cheapestSku.getPrice());
            detail.setFootprintTime(footprintTime);
            detail.setDeleteFlag(flag);
            return detail;
        }
        return null;
    }

    private List<SpuSkuDetail> filterDetailsWithDeleteFlagZero(List<SpuSkuDetail> details) {
        return details.stream()
                .filter(detail -> detail.getDeleteFlag() == 0)
                .collect(Collectors.toList());
    }

    @Override
    public void addFootPrint(Long userId, Long spuId, Date footprintTime) {
        String redisKey = "user:" + userId + ":foot";
        Object cachedDetails = redisUtil.get(redisKey);
        List<SpuSkuDetail> detailsList = (List<SpuSkuDetail>) cachedDetails;
        boolean exists = false;
        if (cachedDetails instanceof List) {
            for (SpuSkuDetail detail : detailsList) {
                if (detail.getId().equals(spuId)) {
                    //修改
                    detail.setDeleteFlag(0);
                    detail.setFootprintTime(footprintTime);
                    exists = true;
                    break;
                }
            }
        }
        if (!exists) {
            //添加
            SpuSkuDetail detail = addFootPrints(spuId, footprintTime, 0);
            detailsList = detailsList != null ? detailsList : new ArrayList<>();
            detailsList.add(detail);
        }
        redisUtil.set(redisKey, detailsList);
    }

    @Override
    public boolean deleteFoot(Long userId, Long spuId) {
        String redisKey = "user:" + userId + ":foot";
        Object cachedDetails = redisUtil.get(redisKey);
        if (cachedDetails instanceof List) {
            List<SpuSkuDetail> details = (List<SpuSkuDetail>) cachedDetails;
            boolean isDeleted = false;
            for (SpuSkuDetail detail : details) {
                if (detail.getId().equals(spuId)) {
                    detail.setDeleteFlag(1);
                    isDeleted = true;
                    break;
                }
            }
            if (isDeleted) {
                redisUtil.set(redisKey, details);
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean deleteAllFoot(Long userId) {
        String redisKey = "user:" + userId + ":foot";
        boolean hasKey = redisUtil.hasKey(redisKey);
        if (hasKey) {
            asyncSyncFootWithDatabaseOnLogout(userId);
            baseMapper.updateDeleteFlagByUserId(userId);
            redisUtil.delete(redisKey);
            return true;
        }
        return false;
    }

    @Override
    public void asyncSyncFootWithDatabaseOnLogout(Long userId) {
        String redisKey = "user:" + userId + ":foot";
        Object cachedDetails = redisUtil.get(redisKey);

        // 从数据库获取当前用户的足迹数据
        List<FootPrint> dbFootprints = baseMapper.selectFootprintsByUserId(userId);
        Map<Long, FootPrint> dbFootprintMap = dbFootprints.stream()
                .collect(Collectors.toMap(FootPrint::getSpuId, Function.identity()));

        // 如果Redis中有足迹数据
        if (cachedDetails instanceof List) {
            List<SpuSkuDetail> redisFootprints = (List<SpuSkuDetail>) cachedDetails;
            // 创建Redis足迹映射，以便于通过ID快速查找
            Map<Long, SpuSkuDetail> redisFootprintMap =
                    redisFootprints.stream()
                            .collect(Collectors.toMap(SpuSkuDetail::getId, Function.identity()));

            for (SpuSkuDetail redisFootprint : redisFootprintMap.values()) {
                Long spuId = redisFootprint.getId();
                FootPrint dbFootprint = dbFootprintMap.get(spuId);
                Integer redisDeleteFlag = redisFootprint.getDeleteFlag();
                Date redisTime = redisFootprint.getFootprintTime();

                if (dbFootprint != null) {
                    // 如果Redis的时间更晚，则更新数据库中的足迹时间
                    if (redisTime.after(dbFootprint.getFootTime())) {
                        baseMapper.updateFootprintTime(dbFootprint.getId(), redisTime);
                    }
                    baseMapper.updateDeleteFlag(dbFootprint.getId(), redisDeleteFlag);
                } else {
                    // 添加新足迹
                    baseMapper.insertFootprint(new FootPrintPo(userId, spuId, redisFootprint.getFootprintTime(), redisDeleteFlag));
                }
            }
        }
        // 同步完成后，删除Redis中的足迹数据
        redisUtil.delete(redisKey);
    }

}




